#include "csvParser.h"
 
CsvParser::CsvParser()
{
}
 
CsvParser::CsvParser(const string &fielname)
{
	if (!Parser(fielname))
		throw "can't is this create parser error";
}
 
CsvParser::~CsvParser()
{
}
 
bool CsvParser::Load(const string &filename,string &Data)
{
	FILE *pfile = fopen(filename.c_str(),"rb");
	if (!pfile)
		return false;
 
	long len=0;
	fseek(pfile, 0, SEEK_END);
	len = ftell(pfile);
	char *fileBuff = new char[len + 1];
	fseek(pfile,0,0);
	fread(fileBuff,1,len,pfile);
	fclose(pfile);
	fileBuff[len] = 0;
	Data.assign(fileBuff, len);
	delete[]fileBuff;
	return true;
}
bool CsvParser::Parser(const string &filename)
{
	m_head.clear();
	m_rowCount.clear();
	string text;
	if (!Load(filename, text) || text.size() == 0)
		return false;
 
 
	enum StateField
	{
		NewFiedlState,//开始新的字段
		NonFieldState,//非引号字段
		QuotesField,//引号字段
		FieldSeparator,//字段分隔
		QuoteInQuoteField,//引号中的引号字段
		RowField,//分隔符/r
		Error//语法错误
	};
 
	Row fields;
	string strfield;
	StateField State=NewFiedlState;
	for (int i = 0, size = text.size(); i < size; i++)
	{
		char ch = text[i];
		
		switch (State)
		{
		case NewFiedlState:
		{
            if (ch == ',')
            {
                fields.push_back("");
                strfield.clear();
                State = FieldSeparator;
            }
            else if (ch == '"')
            {
                State = QuotesField;
            }
            else if (ch == '\r'||ch=='\n')
            {
                this->error = "语法错误：开头表出现空格";
                State = Error;
            }
            else
            {
                strfield.push_back(ch);
                State = NonFieldState;
            }
 
		}
		break;
		case NonFieldState:
		{
            if (ch == ',')
            {
                fields.push_back(strfield);
                strfield.clear();
                State = FieldSeparator;
            }
            else if (ch == '\r')
            {
                fields.push_back(strfield);
                State = RowField;
            }
            else
            {
                strfield.push_back(ch);
            }
		}
		break;
		case QuotesField:
		{
							if (ch == '"')
								State = QuoteInQuoteField;
							else
							{
								strfield.push_back(ch);
							}
		}
			break;
		case FieldSeparator:
		{
            if (ch == ',')
            {
                fields.push_back("");
            }
            else if (ch == '"')
                State = QuotesField;
            else if (ch == '\r')
            {
                fields.push_back("");
                State = RowField;
            }
            else
            {
                strfield.push_back(ch);
                State = NonFieldState;
            }
		}
		break;
		case QuoteInQuoteField:
		{
			if (ch == '"')
			{
				strfield.push_back(ch);
				State = QuotesField;
			}
			else if (ch == '\r')
			{
				fields.push_back(strfield);
				State = RowField;
			}
			else if (ch == ',')
			{
				fields.push_back(strfield);
				strfield.clear();
				State = FieldSeparator;
			}
			else
			{
				this->error = "语法错误:转义字符错误 ,不能完成转义";
				State = Error;
			}
 
		}
			break;
		case RowField:
		{
            if (ch == '\n')
            {
                m_rowCount.push_back(fields);
                fields = Row();
                strfield.clear();
                State = NewFiedlState;
            }
            else
            {
                this->error = "语法错误,没有紧跟 换行";
                State = Error;
            }
		}
			break;
		case Error:
		{
					  return false;
		}
			break;
		default:
			break;
		}
 
	}
	switch (State)
	{
	case NewFiedlState:
		break;
	case NonFieldState:
		fields.push_back(strfield);
		m_rowCount.push_back(fields);
		break;
	case QuotesField:
		this->error = "语法错误 ,引用字段未闭合";
		break;
	case FieldSeparator:
		fields.push_back(strfield);
		m_rowCount.push_back(fields);
		break;
	case QuoteInQuoteField:
		fields.push_back(strfield);
		m_rowCount.push_back(fields);
		break;
	case RowField:
 
		break;
	case Error:
 
		break;
	}
	if (!error.empty())
	{
		return false;
	}
	setHead();
	return true;
}
 
void CsvParser::setHead()
{
	m_head.clear();
	for (int i = 0; i < m_rowCount[0].getSize(); i++)
	{
		m_head.push_back(m_rowCount[0][i]);
	}
	for (int i = 0; i < m_rowCount.size(); i++)
	{
		m_rowCount[i].setHeader(&m_head);
	}
 
}